import json
import os
import sys
import time
from os import system
import re
from PyQt6.QtCore import QThread, pyqtSignal
from PyQt6.QtWidgets import QWidget, QApplication, QMessageBox
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from gui.Q1LJay import Ui_Form
from webui.webbase.webuicore import CaseManage, url, PageElementBase
from mongo.mongobase import WebMongo

class GUIError(Exception):
    def __init__(self, msg):
        super().__init__(msg)


class MyUIThread(QThread):

    def __init__(self, signal):
        super().__init__()
        self.start_signal = signal

    def run(self):
        system("pytest ../webui/webbase/webuicore.py::TestPageBase")
        self.logtime = time.strftime(f'%Y-%m-%d')
        # print(self.logtime)
        with open(f'../report/UI1{self.logtime}') as f:
            log = f.read()

        self.start_signal.emit(f'{log}'
                               f'日志只记录测试用例的执行(不代表测试通过)，测试用例通过率详情请查看测试报告')


class MyUITestThread(QThread):

    def __init__(self, locatoe, signal):
        super().__init__()
        self.locatoe = locatoe
        # print(self.locatoe)
        self.test_signal = signal

        self.options = webdriver.ChromeOptions()
        self.options.add_argument('headless')
        self.driver = webdriver.Chrome(executable_path='../webui/webbase/chromedriver', options=self.options)

        self.driver.get(url)
        self.driver.implicitly_wait(5)

    def run(self):
        try:
            a = self.locatoe.split(',')
            # print(a)
            ele_by = a[0].strip()
            ele_value = a[1].strip()
            # print(ele_by)
            # print(ele_value)
            by_dict = {'xpath': By.XPATH,
                       'id': By.ID,
                       'class_name': By.CLASS_NAME,
                       'link_text': By.LINK_TEXT
                       }
            ele_by = re.compile(r'\"(.*)\"').findall(ele_by)[0]
            if ele_by in by_dict.keys():
                try:
                    by = by_dict[ele_by]

                    # print(ele_by)
                    ele_value = re.compile(r'\"(.*)\"').findall(ele_value)[0]
                    print(ele_value)
                    ele_value = ele_value.replace('\\', '')
                    print(ele_value)

                    ele_msg = self.driver.find_element(by, ele_value)

                    is_dis = ele_msg.is_displayed()
                    is_enb = ele_msg.is_enabled()
                    text = ele_msg.text

                    msg = f'元素是否可见:{is_dis},元素是否可用:{is_enb},元素的文本信息:{text}'
                    self.driver.close()

                    self.test_signal.emit(msg)
                except:
                    msg = f'没有找到元素{ele_value}，请检查'
                    self.test_signal.emit(msg)
            else:
                msg = f'{ele_by}定位方式错误,请检查'
                self.test_signal.emit(msg)

        except:
            QMessageBox.warning(self, '消息', '光标选中的信息错误，请用光标选中需要定位的元素')


class QmyWidget(QWidget):
    start_uilog_signal = pyqtSignal(str)
    test_ele_signal = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)  # 调用父类构造函数，创建窗体
        self.ui = Ui_Form()  # 创建UI对象
        self.ui.setupUi(self)  # 构造UI界面
        self.init_connect()

    ##  ==============自定义功能函数========================

    ##  ==============event处理函数==========================
    def init_connect(self):
        # ui界面保存按钮点击
        self.ui.webui_toolButton_add.clicked.connect(self.click_addButton)
        # ui界面汇总按钮点击
        self.ui.webui_toolButton_merge.clicked.connect(self.click_mergeButton)
        # ui界面检查按钮点击
        self.ui.webui_toolButton_check.clicked.connect(self.click_button_check)
        # ui界面清理按钮点击
        self.ui.webui_toolButton_clean.clicked.connect(self.element_test)
        # ui界面执行按钮点击
        self.ui.webui_toolButton_start.clicked.connect(self.click_startButton)
        # MyUIThread.start_uilog_signal.connect(self.start_ui_log)

        #数据库测试按钮点击

        #数据库连接
        self.ui.pushButton_client.clicked.connect(self.mongo_client)
        #上传用例
        self.ui.pushButton_push.clicked.connect(self.case_push)
        #下载用例
        self.ui.pushButton_load.clicked.connect(self.load_case)



        # ui自定义信号 日志读写
        self.start_uilog_signal.connect(self.start_ui_log)

        # 自定义信号测试元素
        self.test_ele_signal.connect(self.ele_w)

        # 点击查看报告：
        self.ui.report_toolButton_report.clicked.connect(self.click_report_html)

        # 点击查看日志：
        self.ui.report_toolButton_log.clicked.connect(self.click_checkButton)

        # 点击配置查看
        self.ui.config_cheak_toolButton_2.clicked.connect(self.click_config)
        # 点击保存配置
        self.ui.config_add_toolButton.clicked.connect(self.click_add_config)

    ##  ==========由connectSlotsByName()自动连接的槽函数============

    ##  =============自定义槽函数===============================
    # 保存UI测试用例
    def click_addButton(self):

        casedata = self.ui.textEdit_uiadd.toPlainText()

        casejson = json.loads(casedata)
        caselen = 0
        for key, value in casejson.items():
            caselen += 1
        filename = value['页面名称']
        with open(f'../webui/webuidata/webtestcase/{filename}.json', mode='a+') as afile:
            json.dump(casejson, afile, indent=4, ensure_ascii=False)

        QMessageBox.information(self, '新增UI测试用例', f'成功保存{caselen}条测试用例')
        # case_=webuicore.CaseManage.add_casefile(casejson)

    # 汇总按钮点击
    def click_mergeButton(self):
        casemanage = CaseManage(casepath='../webui/webuidata/webtestcase')
        caselen = casemanage.save_json()
        QMessageBox.information(self, '汇总成功', f'成功汇总{caselen}条测试用例')

    # 检查测试用例
    def click_button_check(self):

        if not os.path.exists(f'../webui/webuidata/caselist.json'):
            QMessageBox.warning(self, '消息', '请先汇总测试用例再检查')
            # raise GUIError(f'没有找到文件caselist.json')
        else:
            with open(f'../webui/webuidata/caselist.json', encoding='gbk') as f:
                case = f.read()

            self.ui.textEdit_uiadd.setText(case)

    # 测试元素定位
    def element_test(self):
        self.locatoe = self.ui.textEdit_uiadd.textCursor().selectedText()
        if not self.locatoe:
            QMessageBox.warning(self, '消息', '请先选中要检查的元素')

        # print(self.t_locatoe)
        else:
            self.thread = MyUITestThread(self.locatoe, self.test_ele_signal)

            self.thread.start()

        # try:

        # except:
        #     QMessageBox.warning(self, '消息', '光标选中的元素无法定位，请检查')

    # 测试元素信息写入
    def ele_w(self, msg):

        if msg:
            # msg = json.loads(msg)

            self.ui.textEdit_2.setText(msg)
        else:
            self.ui.textEdit_2.setText('未知错误')

        # #检查日志按钮点击

    def click_checkButton(self):
        self.logtime = time.strftime(f'%Y-%m-%d')

        if not os.path.exists(f'../report/UI1{self.logtime}'):
            QMessageBox.warning(self, '消息', '今日没有日志信息，请先执行用例')
            # raise GUIError(f'没有找到文件caselist.json')
        else:
            with open(f'../report/UI1{self.logtime}') as f:
                log = f.read()

            # self.ui.textEdit_3.setText(log)
            self.ui.textEdit_3.setText(f'{log}'
                                       f'日志只记录测试用例的执行，测试用例通过率详情请查看测试报告')

    # 查看测试报告
    def click_report_html(self):
        import webbrowser
        a = os.getcwd()
        path = os.path.abspath(os.path.join(os.getcwd(), ".."))

        try:

            webbrowser.open_new_tab(f'{path}/report/UIreport.html')

        except:
            QMessageBox.warning(self, '消息', '没有生成测试报告，请先执行用例')

    # 执行UI测试用例
    def click_startButton(self):
        # system("cd ../webui/webbase/")
        self.thread = MyUIThread(self.start_uilog_signal)

        self.thread.start()

    def start_ui_log(self, log):
        self.ui.textEdit_2.setText(log)

    def click_report(self):
        pass

    # 查看配置信息
    def click_config(self):
        try:
            with open('../config/环境配置.json') as f:
                config = f.read()
            self.ui.textEdit.setText(config)



        except:
            QMessageBox.warning(self, '警告', '没有找到配置文件')

    # 保存配置信息
    def click_add_config(self):
        config = self.ui.textEdit.toPlainText()
        try:
            with open('../config/环境配置.json', mode='w+') as f:
                f.write(config)
        except:
            QMessageBox.warning(self, '警告', '保存失败，请检查配置文件是否冲突')

        QMessageBox.information(self, '成功', '保存成功')

    #获取数据库信息
    def get_mongo(self):
        self.mongoserver=self.ui.lineEdit_mongodbserver.text()
        self.mongodb=self.ui.lineEdit_dbname.text()
        return self.mongoserver,self.mongodb

    # 数据库连接
    def mongo_client(self):
        mongo_=self.get_mongo()
        try:
            self.mongodb=WebMongo(mongo_)
            # datalist=self.mongodb.myclient.list_database_names()

            QMessageBox.information(self, '消息', '连接成功')

        except:
            QMessageBox.information(self, '消息', '连接失败，请检查服务器地址及端口信息是否正确')


    #上传用例
    def case_push(self):
        try:
            mongo_=self.get_mongo()
            momgolient=WebMongo(*mongo_)
            momgolient.json_to_mongo()
            QMessageBox.information(self, '消息', '上传成功')
        except:
            QMessageBox.information(self, '错误', '上传失败，请检查数据库服务器是否正确连接')





    #下载用例
    def load_case(self):

        try:

            mongo_ = self.get_mongo()
            momgolient = WebMongo(*mongo_)
            momgolient.save_json()


            QMessageBox.information(self, '消息', '下载成功')

        except:
            QMessageBox.information(self, '错误', '下载失败，请检查数据库服务器是否正确连接')





##  ============窗体测试程序 ================================
if __name__ == "__main__":
    # 用于当前窗体测试
    app = QApplication(sys.argv)  # 创建GUI应用程序

    form = QmyWidget()  # 创建窗体
    form.show()

    sys.exit(app.exec())
